//
// Data model
//

function SerializableObject()
{
    this.serialize = function()
    {
        return $.toJSON(this, false, true);
    }
    
    this.deserialize = function(json)
    {
        for (var k in this)
            if (typeof this[k] != 'function')
                delete this[k];
        
        if (typeof(json) == 'string')        
            json = $.evalJSON(json);
        
        for (k in json)
            this[k] = json[k];
    }
}

function Mockup()
{
    this.id = '';
    this.tag = '';
    this.img = '';
    this.title = '';
    this.comment = '';
    this.spots = [];
	this.isDefault = false;
    
    this.load = function(id, obj)
    {
		try 
		{
			this.deserialize(obj);
			this.id = id;
			
			return this;
		}
		catch(e){}
		return null;
    }
	
	this.fixSpots = function(canvas)
	{
		for (var i in this.spots)
            if (this.spots[i])
                this.spots[i] = canvas._fixRectBounds(this.spots[i]);
	}

    this.deleteSpot = function(index)
    {
        if (index in this.spots)
            delete this.spots[index];
    }

    this.addSpot = function(spot)
    {
      this.spots.push(spot);
      return this.spots.length - 1;
    }

    this.clearSpots = function()
    {
        this.spots = [];
    }
	
	this.spotsCount = function()
	{
		var res = 0;
		for (var i in this.spots)
			if (this.spots[i])
				res += 1;
		return res;
	}
}

Mockup.prototype = new SerializableObject();

function Project()
{
    var self = this;
    
    this.mockups = {};
    this._file = '';
    this._dir = '';
    this.title = 'Untitled';
    this._modified = false;
    
    this.clear = function()
    {
        /*for (var i in this._mockups)
            delete this._mockups[i];*/
		this._mockups = [];
		this._modified = true;
    }
    
    this.load = function(filePath)
    {
		try 
		{
			filePath = getLocalPath(filePath);
			this.deserialize(loadFile(filePath));
			this.mockups_tags = {};
			
			for (var id in this.mockups) {
				this.mockups[id] = (new Mockup()).load(id, this.mockups[id]);
				this.mockups_tags[this.mockups[id].tag] = id;
			}
			this._file = filePath;
			this._dir = getDirFromPath(filePath);
			this._modified = false;
			this._isnew = false;
			
			return this;
		}
		catch(e){}
		return null;
    }
    
    this.save = function(filePath)
    {
        filePath = getLocalPath(filePath);
        try
        {
            if (saveFile(filePath, this.serialize()))
            {
				if (this._file && (this._file != filePath)) 
				{
					var newDir = getDirFromPath(filePath);
					var images = enumerateDirectory(this._dir + 'img/');
					for(var i = 0; i < images.length; ++i)
						copyFile(newDir + 'img/' + images[i], this._dir + 'img/' + images[i]); 
					this._file = filePath;
				}
                this._modified = false;
                return true;
            }
        }
        catch(e) {}

        return false;
    }
	
	this.build = function()
	{
		if (!this._file)
			return false;
		var bd = this._dir + 'build/';
		var cd = getCurrentDir();
		var rd =  cd + 'res/'
		var s = loadFile(rd + 'index.html');
		s = s.replace(/%title%/g, this.title);
		s = s.replace(/%initSlide%/g, this.defaultMockup());
		var res = saveFile(bd + 'index.html', s);
		
		for (var i in this.mockups)
			res &= copyFile(bd + 'img/' + this.mockups[i].img, this._dir + 'img/' + this.mockups[i].img);
		
		res &= copyFile(bd + 'js/storyboard.js', rd + 'js/storyboard.js');
		res &= copyFile(bd + 'js/tiddly.js', cd + 'js/tiddly.js');
		res &= copyFile(bd + 'js/jquery.js', cd + 'js/jquery.js');
		res &= saveFile(bd + 'js/data.json', 'mockupsData = ' + $.toJSON(this.mockups, true, true));
		// TODO : custom CSS 
		res &= copyFile(bd + 'css/storyboard.css', rd + 'css/storyboard.css');
		
		return res;
	}
    
	this.defaultMockup = function()
	{
		for (var i in this.mockups)
			if (this.mockups[i].isDefault)
				return i;
		return null;
	}
	
	this.setDefaultMockup = function(mid)
	{
		var i = this.defaultMockup();
		if (i)
			this.mockups[i].isDefault = false;
		this.mockups[mid].isDefault = false;
	}
	
    this.getMockupByTag = function(tag)
    {
        return this.mockups[this.mockups_tags[tag]];
    }

    this.displayTitle = function()
    {
        return (this._modified ? '*' : '') + 
			this.title + 
			' [' + 
			(this._file ? getFileNameFromPath(this._file) : 'not saved') + 
			']';
    }
	
	this.needsSave = function()
	{
		return !this._file || this._modified;
	}
	
	this.deleteMockup = function(mid)
	{
		if (!(mid in this.mockups))
			return;
		delete this.mockups_tags[this.mockups[mid].tag];
		delete this.mockups[mid];
		this._modified = true;
	}
	
	this.addMockup = function(mockup)
	{
		// TODO: TODO
	}
    
    this.changeMockupTag = function(id, newTag)
    {
		if (newTag == m.tag)
			return true;
		if (!(id in this.mockups))
			return false;
        var m = this.mockups[id];
        if (typeof(m) != 'object')
            return false;
        if (newTag in this.mockups_tags)
            return false;
        var oldTag = m.tag;
		m.tag = newTag;
        delete this.mockups_tags[oldTag];
		this.mockups_tags[newTag] = id;
        return true;
		this._modified = true;
    }
}

Project.prototype = new SerializableObject();

//
// UI methods
//

function clearSurface(canvas)
{
	$('h1:first span').text('No project selected');
	$('#mockups-tools *').attr('disabled', 'disabled');
	$('#properties-form').hide();
    canvas.clearCanvas();
    $('#thumbs .thumb').remove();
    $('#mockup').attr('src', 'img/empty.gif');
}

function loadProject(project, canvas, initial_mockup)
{
	// initializing surface
    clearSurface(canvas);
	if (!project)
		return;
	
    $('h1:first span').text(project.displayTitle());
	$('#mockups-tools *').attr('disabled', '');
	$('#properties-form').show();
	
    // creating mockups thumbnails
    var thumbs = $('#thumbs');
    for (var t in project.mockups)
    {
        var m = project.mockups[t];
        var d = thumbs.append('<div class="thumb"></div>').find('.thumb:last');
		d.attr('_mid', m.id);
        d.mouseover(function() {$(this).find('.thumb-hover').show();});
        d.mouseout(function() {$(this).find('.thumb-hover').hide();});
		d.click(function() {loadMockup(project.mockups[$(this).attr('_mid')], canvas); return false;});
        d.append('<div class="thumb-hover" style="display: none;"></div>');        
        d.append('<img src="' + project._dir + '/img/' + m.img + '" alt="' + m.tag + '" class="captify" />');
        d = d.find('.thumb-hover');
        d.append('<div class="tools"><a href="#">x</a></div>'); 
		d.find('a').attr('_mid', m.id);
		d.find('a').click(function() 
		{
			project.deleteMockup($(this).attr('_mid')); 
			loadProject(project, canvas, initial_mockup != m.id ? initial_mockup : undefined);
			return false;
		});                
    }
    // set thumbs titles
	$('img.captify').captify();				
	
    // load first mockup or current mockup
    for (t in project.mockups)
    {
		if (typeof(initial_mockup) == 'undefined')
			initial_mockup = t;
        if (initial_mockup == t)
        {
            loadMockup(project.mockups[t], canvas);
			break;
        }
    }
	
	// binding to canvas events
	$('#canvas').bind('rectCreated', function(e, id) 
	{
		var rect = $('#canvas').find('#' + id)[0];
		if ($(rect).attr('_spotIndex'))
		  return;
		var i = currentMockup.addSpot({left: rect.offsetLeft, top: rect.offsetTop, width: rect.clientWidth, height: rect.clientHeight, 
		  title: '', link: '', _rectId: rect.id});
		$(rect).attr('_spotIndex', i);
		project._modified = true; 
		setCurrentSpot(rect);
  	});	
	$("#canvas").bind('currentRectChanged', function(e, rect) {setCurrentSpot(rect)});	
	$("#canvas").bind('rectResized', function(e, rect){project._modified = true; setCurrentSpot(rect)});
	$("#canvas").bind('rectMoved', function(e, rect){project._modified = true; setCurrentSpot(rect)});
	$("#canvas").bind('rectDeleted', function(e, id)
	{
		project._modified = true;
		for (var i in currentMockup.spots)
			if (currentMockup.spots[i] && (currentMockup.spots[i]._rectId == id))
				currentMockup.deleteSpot(i); 
		setCurrentSpot(null);
	});
}

function loadMockup(mockup, canvas)
{
	currentMockup = mockup;
    canvas.clearCanvas();
    $('#mockup').attr('src', project._dir + 'img/' + mockup.img);
    
    $('#mockup').onImagesLoad({selectorCallback: function()
		{
			$(canvas._canvas).css('width', $('#mockup').attr('width') + 'px');
			$(canvas._canvas).css('height', $('#mockup').attr('height') + 'px');
			mockup.fixSpots(canvas);
			for (var i = 0; i < mockup.spots.length; ++i) 
                if (mockup.spots[i])
                {
                    currentSpot = mockup.spots[i];
                    currentSpot._rectId = canvas.createRect(currentSpot.left, currentSpot.top, currentSpot.width, currentSpot.height,
                        {title: currentSpot.title, _spotIndex: i});
                }
		}
	})
}

function clearMockup(canvas)
{
	currentMockup.clearSpots();
	canvas.clearCanvas();
}

function setCurrentSpot(rect)
{
	if (rect)
  	{
    	currentSpot = currentMockup.spots[parseInt($(rect).attr('_spotIndex'))];
	    currentSpot.width = rect.clientWidth;
	    currentSpot.height = rect.clientHeight;
	    currentSpot.left = rect.offsetLeft;
	    currentSpot.top = rect.offsetTop;
  	}
    else
        currentSpot = null;
    showSpotProperties();
}

function showSpotProperties()
{
    if (currentSpot)
    {
        $('.hotspot-props').show();
        $('#spot-id').text(currentSpot._rectId);
        $('#spot-width').text(currentSpot.width);
        $('#spot-height').text(currentSpot.height);
        $('#spot-left').text(currentSpot.left);
        $('#spot-top').text(currentSpot.top);
		$('#spot-link').attr('value', currentSpot.link);
		$('#spot-title').attr('value', currentSpot.title);
    }
    else
        $('.hotspot-props').hide();    
    $('h1:first span').text(project.displayTitle());
}

function showMockupProperties()
{
	
}

function showProjectProperties()
{
	
}
